package com.byd.base;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import android.content.Context;

public abstract class BaseSelectAdapter<T, H extends BaseHolder> extends BaseAdapter<T, H> {
	private final ArrayList<T> mSelectList;
	private OnSelectChangedListener mListener;

	public BaseSelectAdapter(Context context) {
		super(context);
		mSelectList = new ArrayList<T>();
	}

	@Override
	public void update(List<T> data) {
		super.update(data);
		if(mList == null) {
			mSelectList.clear();
			notifyDataSetChanged();
			return;
		}
		synchronized (mSelectList) {
			final int size = mSelectList.size();
			for (int i = size - 1; i >= 0; i--) {
				if(!mList.contains(mSelectList.get(i))) {
					mSelectList.remove(i);
				}
			}
			notifyDataSetChanged();
			reportSelectChanged(-2, true);
		}
	}

	public void addSelect(T t) {
		mSelectList.add(t);
		reportSelectChanged(mList.indexOf(t), true);
		notifyDataSetChanged();
	}

	public void addSelect(int position) {
		addSelect(getItem(position));
	}

	public void removeSelect(T t) {
		mSelectList.remove(t);
		reportSelectChanged(mList.indexOf(t), false);
		notifyDataSetChanged();
	}

	public void removeSelect(int position) {
		removeSelect(getItem(position));
	}

	public boolean isSelect(T t) {
		return mSelectList.contains(t);
	}

	public boolean isSelect(int position) {
		return isSelect(getItem(position));
	}

	public void changeSelect(T t) {
		if(isSelect(t)) {
			removeSelect(t);
		}
		else {
			addSelect(t);
		}
	}

	public void changeSelect(int position) {
		changeSelect(getItem(position));
	}

	public void selectAll() {
		mSelectList.clear();
		if(mList != null) {
			mSelectList.addAll(mList);
		}
		reportSelectChanged(-1, true);
		notifyDataSetChanged();
	}

	public void selectNone() {
		mSelectList.clear();
		reportSelectChanged(-1, false);
		notifyDataSetChanged();
	}

	public LinkedList<T> getSelects() {
		if(getCount() > 0) {
			final LinkedList<T> list = new LinkedList<T>();
			synchronized (mList) {
				for (final T t : mList) {
					if(mSelectList.contains(t)) {
						list.add(t);
					}
				}
			}
			return list;
		}
		return null;
	}

	public int getSelectSize() {
		return mSelectList.size();
	}

	public boolean isSelectAll() {
		return getSelectSize() > 0 && getSelectSize() == getCount();
	}

	public void reportSelectChanged(int position, boolean select) {
		if(mListener != null) {
			mListener.onSelectChanged(this, position, select);
		}
	}

	public void setOnSelectChangedListener(OnSelectChangedListener listener) {
		mListener = listener;
	}

	public interface OnSelectChangedListener {
		public void onSelectChanged(BaseSelectAdapter<?, ?> adapter, int position, boolean select);
	}
}
